package com.bls.executor;

import com.bls.action.BLSAction;
import com.bls.constant.ResultCodeEnum;
import com.bls.exception.MyException;
import com.bls.executor.parser.V3Lexer;
import com.bls.executor.parser.V3Parser;
import com.bls.executor.parser.Visitor;
import com.bls.utils.ThrowingErrorListener;
import com.rabbitmq.client.Channel;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenSource;
import org.antlr.v4.runtime.tree.ParseTree;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

public class Executor {
    public static boolean errFlag = false;
    public static String errMsg;

    public static void main(String[] args) throws MyException {
//        runScript("张三在喇叭帮区执行喇叭工具的发声部件。","001",new HashMap<String,String>(),"");
//        runScript("张三在喇叭帮区执行喇叭工具的发声部件，参数为测试，参数为设备出现故障。","001",new HashMap<String,String>(),"");
//        runScript("当在测试帮区监听到消息总线设备故障消息的类型，则张三在当前帮区执行消息板工具，消息板为测试消息室，消息内容为设备出现故障。","",null,"");
        runScript("当在 2019级梁子豪个人工作区 帮区监听到 设备故障 消息的类型，则 梁子豪 在 2019级梁子豪个人工作区 帮区执行消息板工具,消息板为 2019级梁子豪论文消息板 ，消息内容为 XX 。", null, 1l);
//        runScript("当在 2019级梁子豪个人工作区 帮区监听到消息总线 设备故障 消息的类型，则 张三 在 2019级梁子豪个人工作区 帮区执行消息板工具,消息板为 2019级梁子豪论文消息板 ，消息内容为 XX 。","",null,"");

//        runScript(" 张三 在 喇叭 帮区执行 喇叭 工具的 发声 部件， 参数 为 值 ，返回结果为 A 。","",null,"");
    }

    public static boolean runScript(String script, String bandId, Map env, String accessToken) {
        CharStream input = CharStreams.fromString(script);

        //词法分析
        V3Lexer lexer = new V3Lexer(input);
        CommonTokenStream tokens = new CommonTokenStream((TokenSource) lexer);

        //语法分析
        V3Parser parser = new V3Parser(tokens);
        ParseTree tree = parser.script();

        Visitor myVisitor = new Visitor();
        Visitor.scriptEnvironment = env;
        myVisitor.visit(tree);
        return true;
    }

    public static Map<String, Object> runScript(String script, Map env, long scriptId) throws MyException {
        CharStream input = CharStreams.fromString(script);

        //词法分析
        V3Lexer lexer = new V3Lexer(input);
        CommonTokenStream tokens = new CommonTokenStream((TokenSource) lexer);

        //语法分析
        V3Parser parser = new V3Parser(tokens);
        parser.removeErrorListeners();
        parser.addErrorListener(ThrowingErrorListener.INSTANCE);
        ParseTree tree = parser.script();

        if (errFlag) {
            errFlag = false;
            throw new MyException(ResultCodeEnum.PARSER_ERROR.getCode(), ResultCodeEnum.PARSER_ERROR.getMsg(), errMsg);
        }

        Visitor myVisitor = new Visitor();
        Map<String, Object> map = myVisitor.visit(tree);
        if(map.containsKey("task")){
            Future task = (Future) map.get("task");
            if (task != null) {
                List<Future> tasks = BLSAction.scriptRunningStatus.getOrDefault(String.valueOf(scriptId), new ArrayList<>());
                tasks.add(task);
                BLSAction.scriptRunningStatus.put(String.valueOf(scriptId), tasks);
            }
        }
        if(map.containsKey("tag")){
            Map<String, Channel> tag = (Map<String, Channel>) map.get("tag");
            if (tag.size() != 0) {
                Map<String, Channel> tags = BLSAction.mqRunningStatus.getOrDefault(String.valueOf(scriptId), new Hashtable<>());
                tags.putAll(tag);
                BLSAction.mqRunningStatus.put(String.valueOf(scriptId), tags);
            }
        }
        return map;
    }
}
